﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KitBuildingWF.Models;
using System.Data;
using System.Windows;
using System.Windows.Forms;

namespace KitBuildingWF.Controls
{
    public class BuildKits
    {
        private List<RequestedKit> kits = new List<RequestedKit>();
        //private List<BuildKitStock> stocks = new List<BuildKitStock>();
        // Map: capital code => Stock Object
        private Dictionary<string, RequestedStock> codeToStock = new Dictionary<string, RequestedStock>();
        private DataSet1 kitDataSet = null;
        
        private List<RequestedStock> allRequestedStock = new List<RequestedStock>();
        //private RequestedStock requestedStock = null;

        public BuildKits() { }

        public BuildKits(Kit kit)
        {
            
        }

        public BuildKits(DataSet1 dataset)
        {
            kitDataSet = dataset;
        }

        /// <summary>
        /// add a single kit
        /// </summary>
        /// <param name="kittoAdd"></param>
        public void AddKits(RequestedKit kittoAdd)
        {
            kits.Add(kittoAdd);
        }

        /// <summary>
        /// add a a list of kits.
        /// </summary>
        /// <param name="kitstoAdd"> List of Kits</param>
        public void AddKits(List<RequestedKit> kitstoAdd)
        {
            foreach (RequestedKit kit in kitstoAdd)
            {
                kits.Add(kit);
            }
        }

        /// <summary>
        /// Clear the list
        /// </summary>
        public void Clear()
        {
            kits.Clear();
        }

        /// <summary>
        /// Calcualte the stock for building kits
        /// </summary>
        public void CalculateAll()
        {
            // visit every kit to be built
            foreach (RequestedKit kit in kits)
            {
                kit.actualBuildNo = kit.requestedNo;
                
                // visit every kit line item 
                foreach (KitLineItem lineItem in kit.contents){
                    RequestedStock requestedStock = null;

                     // construct a stock item if it's not in the list
                    if (codeToStock.ContainsKey(lineItem.itemCapitalCode) == false)
                    {
                        requestedStock = new RequestedStock();
                        
                        requestedStock.productCode = lineItem.itemCapitalCode;

                        DataSet1.StockItemRow[] stockrows = (DataSet1.StockItemRow[])kitDataSet.StockItem.Select("Name = '" + lineItem.itemCapitalCode.Trim() + "'");

                        if (stockrows.Length > 1)
                        {
                            Console.WriteLine("Error: multiple stock items");
                            continue;
                        }

                        if (stockrows.Length == 0)
                        {
                            Console.WriteLine("Error: no stock item matched");
                            continue;
                        }
                        
                        foreach (DataSet1.StockItemRow row in stockrows)
                        {
                            requestedStock.description = row.TITLE;
                            requestedStock.stockIn = Convert.ToInt32(row.STOCK_IN);
                            requestedStock.allocated = Convert.ToInt32(row.ALLOCATED);
                            requestedStock.backOrder = Convert.ToInt32(row.BACKORDER);
                            requestedStock.location = row.LOCATION;

                            requestedStock.s1Supplier = row.S1CODE;
                            requestedStock.s1PartNo = row.S1PARTNO;
                            requestedStock.s1PackQty = Convert.ToInt32(row.S1PACKQTY);
                            requestedStock.s2Supplier = row.S2CODE;
                            requestedStock.s2PartNo = row.S2PARTNO;
                            requestedStock.s2PackQty = Convert.ToInt32(row.S2PACKQTY);
                            requestedStock.s3Supplier = row.S3CODE;
                            requestedStock.s3PartNo = row.S3PARTNO;
                            requestedStock.s3PackQty = Convert.ToInt32(row.S3PACKQTY);
                            requestedStock.s4Supplier = row.S4CODE;
                            requestedStock.s4PartNo = row.S4PARTNO;
                            requestedStock.s4PackQty = Convert.ToInt32(row.S4PACKQTY);

                            break;
                        }
                        requestedStock.availableStock = requestedStock.stockIn - requestedStock.allocated;

                        codeToStock.Add(lineItem.itemCapitalCode, requestedStock);
                    }
                    else
                    {
                        // the stock item also used in other scheduled kits
                        requestedStock = codeToStock[lineItem.itemCapitalCode];
                    }

                    if (requestedStock.availableStock / lineItem.itemQty < kit.actualBuildNo)
                    {
                        kit.actualBuildNo = requestedStock.availableStock / lineItem.itemQty;
                    }

                    KitRequest kr = new KitRequest();
                    kr.kitCode = kit.kitCode;
                    kr.onhold = kit.actualBuildNo * lineItem.itemQty;
                    kr.requested = kit.requestedNo * lineItem.itemQty;
                    requestedStock.AddKitRequest(kr);

                    //requestedStock.onHoldForKits.Add(kit.kitCode, kit.actualBuildNo * lineItem.itemQty);
                    requestedStock.availableStock = requestedStock.availableStock - kit.actualBuildNo * lineItem.itemQty;
                }

            }
        }


        /// <summary>
        /// Get all the processed kits.
        /// call calculate() method before this method
        /// </summary>
        /// <returns></returns>
        public List<RequestedKit> GetPreparedKits()
        {
            return kits;
        }

        /// <summary>
        /// Get all the processed Kits in the a dictionary
        /// Map: KitCode => Kit
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, RequestedKit> GetMappedPreparedKits()
        {
            Dictionary<string, RequestedKit> mappedKits = new Dictionary<string, RequestedKit>();

            foreach (RequestedKit kit in kits)
            {
                mappedKits.Add(kit.kitCode, kit);
            }

            return mappedKits;
        }

        /// <summary>
        /// Get all the prepared stock items
        /// </summary>
        /// <returns></returns>
        public List<RequestedStock> GetPreparedStocks()
        {
            //MessageBox.Show(codeToStock.Count.ToString());

            foreach (var pair in codeToStock)
            {
                allRequestedStock.Add((RequestedStock)pair.Value);
            }

            return allRequestedStock;
        }


    }
}
